/**
 * 
 */
package ac.svn.accesscontrol.ui.helper;

import java.util.HashSet;
import java.util.Set;

import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.SwingUtilities;

import ac.svn.accesscontrol.store.IResources;
import ac.svn.accesscontrol.store.ISVNItem;
import ac.svn.accesscontrol.ui.IUIConstants;
import ac.svn.accesscontrol.ui.UIComponentLibrary;
import ac.svn.accesscontrol.ui.model.ThreadedListModel;
import ac.svn.accesscontrol.utils.Utility;

/**
 * @author Enigmanic
 *
 */
public class ContentLister implements ILister
{
	private boolean listClrRequired = false;
	private ThreadedListModel listModel;
	private JLabel statusLabel;
	private Thread listingThread;
	private JList targetList;
	private Set<ISVNItem> sourceFiles = null;

	//Default constructor
	public ContentLister()
	{
		this.targetList = null;
		this.listModel = null;
		this.statusLabel = null;
		initThread();
	}


	/***
	 *  Constructor based on UIComponentLibrary Publishing.
	 * @param componentId
	 * @param modelId
	 */
	public ContentLister(String componentId,String modelId)
	{
		targetList = (JList) UIComponentLibrary.getComponent(componentId);
		listModel =  (ThreadedListModel) UIComponentLibrary.getComponent(modelId);
		statusLabel = (JLabel) UIComponentLibrary.getComponent(IUIConstants.C_STATUS_LABEL);
		initThread();
	}

	/***
	 *  Constructors will all required components.
	 * @param targetList
	 * @param listModel
	 * @param statusLabel
	 */
	public ContentLister(JList targetList, ThreadedListModel listModel, JLabel statusLabel)
	{
		this.targetList = targetList;
		this.listModel = listModel;
		this.statusLabel = statusLabel;
		initThread();
	}



	/***
	 * Method initializes thread task/ Listing task.
	 */
	private void initThread()
	{
		listingThread = new Thread(new Runnable() 
		{
			@Override
			public void run() 
			{
				//Check items to be displayed
				if(null == sourceFiles)
				{
					return;
				}

				//Check if append is required or new listing
				if(isListClrRequired())
				{
					listModel.clear();
				}

				//Add new data to list Model.
				listModel.addElement(sourceFiles);

				//Update UI at the end of operation.
				SwingUtilities.invokeLater(new Runnable() 
				{
					@Override
					public void run()
					{
						try
						{
							SwingUtilities.updateComponentTreeUI(targetList);
							updateListingCompleteStatus("Listing complete!");
						}
						catch(NullPointerException ne)
						{
							System.err.println("UI Update incomplete!");
						}
					}
				});
			}
		});
	}

	/***
	 * Method is used for listing of ISVNItem type collection on target list view.
	 * @param svnItems
	 */
	public void listItems(Set<ISVNItem> svnItems)
	{
		if(null != sourceFiles)
		{
			synchronized (sourceFiles) 
			{
				sourceFiles = null;
				sourceFiles =  svnItems;
			}
		}
		else
		{
			sourceFiles =  svnItems;
		}

		refresh();
	}

	/***
	 * Set if before every listing, list view clear is required. Default value is false.
	 * @param listClrRequired
	 */
	public void setListClrRequired(boolean listClrRequired) 
	{
		this.listClrRequired = listClrRequired;
	}

	public boolean isListClrRequired() 
	{
		return listClrRequired;
	}

	/***
	 * Method is called to re-display same set of ISVNItem type. 
	 */
	public void refresh()
	{
		if(listingThread.isAlive())
		{
			listingThread.interrupt();
		}
		listingThread.run();
	}

	/***
	 * Method to add single element to List View.
	 * @param svnItem
	 */
	public void addItem(ISVNItem svnItem)
	{
		if(null == sourceFiles)
		{
			sourceFiles= new HashSet<ISVNItem>(1);
		}
		sourceFiles.add(svnItem);
		refresh();
	}

	private void updateListingCompleteStatus(String message)
	{
		if(null != statusLabel)
		{
			statusLabel.setText(message);
			statusLabel.setIcon(Utility.getImageIcon(IResources.LOC_ICN_DONE));
		}
	}

	/**
	 * @return the listModel
	 */
	public ThreadedListModel getListModel() {
		return listModel;
	}

	/**
	 * @param listModel the listModel to set
	 */
	public void setListModel(ThreadedListModel listModel) {
		this.listModel = listModel;
	}

	/**
	 * @return the statusLabel
	 */
	public JLabel getStatusLabel() {
		return statusLabel;
	}

	/**
	 * @param statusLabel the statusLabel to set
	 */
	public void setStatusLabel(JLabel statusLabel) {
		this.statusLabel = statusLabel;
	}

	/**
	 * @return the listingThread
	 */
	public Thread getListingThread() {
		return listingThread;
	}

	/**
	 * @param listingThread the listingThread to set
	 */
	public void setListingThread(Thread listingThread) {
		this.listingThread = listingThread;
	}

	/**
	 * @return the targetList
	 */
	public JList getTargetList() {
		return targetList;
	}

	/**
	 * @param targetList the targetList to set
	 */
	public void setTargetList(JList targetList) {
		this.targetList = targetList;
	}

	/**
	 * @return the sourceFiles
	 */
	public Set<ISVNItem> getSourceFiles() {
		return sourceFiles;
	}

	/**
	 * @param sourceFiles the sourceFiles to set
	 */
	public void setSourceFiles(Set<ISVNItem> sourceFiles) {
		this.sourceFiles = sourceFiles;
	}



}
